import com.zaxxer.hikari.HikariConfig;
import com.zaxxer.hikari.HikariDataSource;

import java.math.BigDecimal;
import java.sql.*;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;

public class UserWalletService {
    private HikariDataSource dataSource;

    public UserWalletService() {
        HikariConfig config = new HikariConfig();
        config.setJdbcUrl("jdbc:mysql://localhost:3306/test");
        config.setUsername("root");
        config.setPassword("password");
        dataSource = new HikariDataSource(config);
    }

    // 查询用户钱包余额
    public BigDecimal getUserWalletBalance(int userId) throws SQLException {
        String sql = "SELECT balance FROM user_wallet WHERE user_id = ?";
        try (Connection conn = dataSource.getConnection();
             PreparedStatement stmt = conn.prepareStatement(sql)) {
            stmt.setInt(1, userId);
            try (ResultSet rs = stmt.executeQuery()) {
                if (rs.next()) {
                    return rs.getBigDecimal("balance");
                } else {
                    throw new RuntimeException("User wallet not found");
                }
            }
        }
    }

    // 用户消费接口
    public void spendMoney(int userId, BigDecimal amount) throws SQLException {
        Connection conn = dataSource.getConnection();
        try {
            conn.setAutoCommit(false);
            BigDecimal userBalance = getUserWalletBalance(userId);
            if (userBalance.compareTo(amount) < 0) {
                throw new RuntimeException("Insufficient balance");
            }
            updateWalletBalance(conn, userId, userBalance.subtract(amount));
            insertWalletTransaction(conn, userId, amount.negate(), "OUT", String.format("Spend %.2f yuan", amount));
            conn.commit();
        } catch (SQLException e) {
            conn.rollback();
            throw e;
        } finally {
            conn.close();
        }
    }

    // 用户退款接口
    public void refundMoney(int userId, BigDecimal amount) throws SQLException {
        Connection conn = dataSource.getConnection();
        try {
            conn.setAutoCommit(false);
            BigDecimal userBalance = getUserWalletBalance(userId);
            updateWalletBalance(conn, userId, userBalance.add(amount));
            insertWalletTransaction(conn, userId, amount, "IN", String.format("Refund %.2f yuan", amount));
            conn.commit();
        } catch (SQLException e) {
            conn.rollback();
            throw e;
        } finally {
            conn.close();
        }
    }

    // 查询用户钱包金额变动明细的接口
    public List<WalletTransaction> getUserWalletTransactions(int userId) throws SQLException {
        String sql = "SELECT * FROM wallet_transaction WHERE user_id = ? ORDER BY created_at DESC";
        try (Connection conn = dataSource.getConnection();
             PreparedStatement stmt = conn.prepareStatement(sql)) {
            stmt.setInt(1, userId);
            try (ResultSet rs = stmt.executeQuery()) {
                List<WalletTransaction> transactions = new ArrayList<>();
                while (rs.next()) {
                    int id = rs.getInt("id");
                    BigDecimal amount = rs.getBigDecimal("amount");
                    String type = rs.getString("type");
                    LocalDateTime createdAt = rs.getObject("created_at", LocalDateTime.class);
                    transactions.add(new WalletTransaction(id, userId, amount, type, createdAt));
                }
                return transactions;
            }
        }
    }

    private void updateWalletBalance(Connection conn, int userId, BigDecimal balance) throws SQLException {
        String sql = "UPDATE user_wallet SET balance = ? WHERE user_id = ?";
        try (PreparedStatement stmt = conn.prepareStatement(sql)) {
            stmt.setBigDecimal(1, balance);
            stmt.setInt(2, userId);
            stmt.executeUpdate();
        }
    }

    private void insertWalletTransaction(Connection conn, int userId, BigDecimal amount, String type, String description) throws SQLException {
        String sql = "INSERT INTO wallet_transaction (user_id, amount, type, description) VALUES (?, ?, ?, ?)";
        try (PreparedStatement stmt = conn.prepareStatement(sql, Statement.RETURN_GENERATED_KEYS)) {
            stmt.setInt(1, userId);
            stmt.setBigDecimal(2, amount);
            stmt.setString(3, type);
            stmt.setString(4, description);
            stmt.executeUpdate();
            try (ResultSet rs = stmt.getGeneratedKeys()) {
                if (rs.next()) {
                    int id = rs.getInt(1);
                    System.out.println("Created wallet transaction " + id);
                }
            }
        }
    }
}